package org.gdstash.ui.stash;

import org.gdstash.file.DDSLoader;
import org.gdstash.item.GDItem;
import org.gdstash.item.GDItemContainer;
import org.gdstash.ui.GDStashFrame;
import org.gdstash.ui.GDUITransfer;
import org.gdstash.util.GDImagePool;

import javax.swing.*;
import javax.swing.event.MouseInputAdapter;
import java.awt.*;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.util.LinkedList;
import java.util.List;

public class GDContainerPane extends JLabel implements GDUIContainer {
    protected static final Color COLOR_RED;
    protected static final Color COLOR_DARK_RED;
    protected static final Color COLOR_WHITE;
    protected static final Color COLOR_GREEN;
    protected GDItemContainer container;
    protected int containerType;
    protected GDUIInventory uiInventory;
    protected GDUITransfer uiTransfer;
    protected Rectangle mouseRect;
    protected int xOffset;
    protected int yOffset;
    protected GDStashFrame frame;

    public GDContainerPane(final int containerType, final int xOffset, final int yOffset, final GDStashFrame frame, final GDUIInventory uiInventory, final GDUITransfer uiTransfer) {
        this.frame = frame;
        this.containerType = containerType;
        this.xOffset = xOffset;
        this.yOffset = yOffset;
        this.uiInventory = uiInventory;
        this.uiTransfer = uiTransfer;
        this.mouseRect = null;
        this.addMouseListener(new GDContainerPageMouseListener());
        this.addMouseMotionListener(new GDContainerPageMouseListener());
    }

    @Override
    public void setContainer(final GDItemContainer container) {
        this.container = container;
        if (container != null) {
            this.containerType = container.getContainerType();
        }
        this.layoutPage();
    }

    @Override
    public BufferedImage getBackgroundImage() {
        BufferedImage img = null;
        switch (this.containerType) {
            case 1: {
                img = GDImagePool.getSharedStashGrid();
                break;
            }
            case 2: {
                img = GDImagePool.getCraftingStashGrid();
                break;
            }
            case 3: {
                img = GDImagePool.getCharStashGrid();
                break;
            }
            case 4: {
                img = GDImagePool.imgCharInventory;
                break;
            }
            case 5: {
                img = GDImagePool.imgCharBag;
                break;
            }
            case 6: {
                img = GDImagePool.imgCharEquipped;
                break;
            }
            default: {
                img = GDImagePool.getSharedStashGrid();
                break;
            }
        }
        return img;
    }

    @Override
    public BufferedImage drawGraphics() {
        GDItem selItem = null;
        if (this.uiTransfer != null) {
            selItem = this.uiTransfer.getSelectedItem();
        }
        final BufferedImage imgBG = this.getBackgroundImage();
        final BufferedImage image = new BufferedImage(imgBG.getWidth(), imgBG.getHeight(), imgBG.getType());
        final Graphics2D g = image.createGraphics();
        if (this.container == null) {
            g.setColor(GDContainerPane.COLOR_DARK_RED);
            g.setComposite(AlphaComposite.getInstance(10, 0.8f));
            g.fillRect(0, 0, imgBG.getWidth(), imgBG.getHeight());
        }
        g.drawImage(imgBG, 0, 0, null);
        Rectangle rect = null;
        if (this.container != null) {
            for (final GDItem item : this.container.getItemList()) {
                final BufferedImage img = item.getFullImage();
                final int x = item.getX() * 32 + GDImagePool.getSharedStashXOffset();
                final int y = item.getY() * 32 + GDImagePool.getSharedStashYOffset();
                if (img != null) {
                    final Color color = item.getOverlayColor();
                    if (color != null) {
                        g.setColor(color);
                        g.setComposite(AlphaComposite.getInstance(10, 0.3f));
                        g.fillRect(x + 1, y + 1, img.getWidth() - 2, img.getHeight() - 2);
                        g.setComposite(AlphaComposite.getInstance(10, 1.0f));
                        g.drawRect(x + 1, y + 1, img.getWidth() - 2, img.getHeight() - 2);
                    }
                    g.drawImage(img, x, y, null);
                }
                if (item == selItem) {
                    rect = new Rectangle(x, y, img.getWidth(), img.getHeight());
                }
            }
        }
        if (rect != null) {
            g.setColor(GDContainerPane.COLOR_GREEN);
            g.drawRect((int) rect.getX(), (int) rect.getY(), (int) rect.getWidth(), (int) rect.getHeight());
            g.drawRect((int) rect.getX() + 1, (int) rect.getY() - 1, (int) rect.getWidth() - 2, (int) rect.getHeight() + 2);
        }
        if (this.mouseRect != null) {
            if (this.isBlocked()) {
                g.setColor(GDContainerPane.COLOR_RED);
            } else {
                g.setColor(GDContainerPane.COLOR_WHITE);
            }
            g.drawRect((int) this.mouseRect.getX(), (int) this.mouseRect.getY(), (int) this.mouseRect.getWidth(), (int) this.mouseRect.getHeight());
            g.drawRect((int) this.mouseRect.getX() + 1, (int) this.mouseRect.getY() - 1, (int) this.mouseRect.getWidth() - 2, (int) this.mouseRect.getHeight() + 2);
        }
        return image;
    }

    @Override
    public int getXOffset() {
        return this.xOffset;
    }

    @Override
    public int getYOffset() {
        return this.yOffset;
    }

    @Override
    public int getHeight() {
        return this.getPreferredHeight();
    }

    @Override
    public int getWidth() {
        return this.getPreferredWidth();
    }

    @Override
    public boolean addItem(final GDItem item, final int action, final int xCoord, final int yCoord) {
        boolean added = false;
        if (this.container != null) {
            int xPos = xCoord;
            int yPos = yCoord;
            int xOff = this.getXOffset();
            int yOff = this.getYOffset();
            if (GDStashFrame.iniConfig.sectUI.graphicScale != 100) {
                xOff = xOff * GDStashFrame.iniConfig.sectUI.graphicScale / 100;
                yOff = yOff * GDStashFrame.iniConfig.sectUI.graphicScale / 100;
            }
            xPos -= xOff;
            yPos -= yOff;
            if (GDStashFrame.iniConfig.sectUI.graphicScale != 100) {
                xPos = xPos * 100 / GDStashFrame.iniConfig.sectUI.graphicScale;
                yPos = yPos * 100 / GDStashFrame.iniConfig.sectUI.graphicScale;
            }
            xPos /= 32;
            yPos /= 32;
            item.setX(xPos);
            item.setY(yPos);
            added = this.container.addItem(item);
        }
        return added;
    }

    @Override
    public boolean deleteItem(final GDItem item, final int action, final boolean update) {
        if (item == null) {
            return true;
        }
        boolean deleted = false;
        if (this.container != null) {
            deleted = this.container.removeItem(item);
            if (update) {
                this.layoutPage();
            }
        }
        return deleted;
    }

    @Override
    public boolean hasChanged() {
        return this.container != null && this.container.hasChanged();
    }

    @Override
    public List<GDItem> getItemList(final int action) {
        final List<GDItem> list = new LinkedList<GDItem>();
        if (this.container == null) {
            return list;
        }
        return this.container.getItemList();
    }

    @Override
    public void refresh() {
        if (this.container != null) {
            this.container.refresh();
            this.layoutPage();
        }
    }

    static {
        COLOR_RED = Color.RED;
        COLOR_DARK_RED = new Color(127, 0, 0);
        COLOR_WHITE = Color.WHITE;
        COLOR_GREEN = new Color(83, 255, 40);
    }

    @Override
    public Dimension getPreferredSize() {
        final BufferedImage image = this.getBackgroundImage();
        final int w = image.getWidth() * GDStashFrame.iniConfig.sectUI.graphicScale / 100;
        final int h = image.getHeight() * GDStashFrame.iniConfig.sectUI.graphicScale / 100;
        return new Dimension(w, h);
    }

    @Override
    public Dimension getMaximumSize() {
        return this.getPreferredSize();
    }

    @Override
    public Dimension getMinimumSize() {
        return this.getPreferredSize();
    }

    public int getPreferredWidth() {
        return (int) this.getPreferredSize().getWidth();
    }

    public int getPreferredHeight() {
        return (int) this.getPreferredSize().getHeight();
    }

    public void layoutPage() {
        if (this.uiTransfer == null) {
            this.mouseRect = null;
        } else if (this.uiTransfer.getSelectedItem() == null) {
            this.mouseRect = null;
        }
        BufferedImage image = this.drawGraphics();
        if (GDStashFrame.iniConfig.sectUI.graphicScale != 100) {
            final int w = image.getWidth() * GDStashFrame.iniConfig.sectUI.graphicScale / 100;
            final int h = image.getHeight() * GDStashFrame.iniConfig.sectUI.graphicScale / 100;
            image = DDSLoader.getScaledImage(image, w, h);
        }
        this.setIcon(new ImageIcon(image));
    }

    private boolean isBlocked() {
        if (this.mouseRect == null) {
            return true;
        }
        if (this.container == null) {
            return true;
        }
        final int xr = (int) this.mouseRect.getX();
        final int yr = (int) this.mouseRect.getY();
        final int wr = (int) this.mouseRect.getWidth();
        final int hr = (int) this.mouseRect.getHeight();
        int wp = this.getPreferredWidth();
        int hp = this.getPreferredHeight();
        if (GDStashFrame.iniConfig.sectUI.graphicScale != 100) {
            wp = wp * 100 / GDStashFrame.iniConfig.sectUI.graphicScale;
            hp = hp * 100 / GDStashFrame.iniConfig.sectUI.graphicScale;
        }
        if (xr + wr >= wp) {
            return true;
        }
        if (yr + hr >= hp) {
            return true;
        }
        if (this.container != null) {
            final GDItem selItem = this.uiInventory.getSelectedItem();
            for (final GDItem item : this.container.getItemList()) {
                if (item == selItem) {
                    continue;
                }
                final BufferedImage img = item.getImage();
                if (img == null) {
                    continue;
                }
                final int xi = item.getX() * 32 + GDImagePool.getSharedStashXOffset();
                final int yi = item.getY() * 32 + GDImagePool.getSharedStashYOffset();
                final int wi = img.getWidth();
                final int hi = img.getHeight();
                if (xr >= xi && xr <= xi + wi) {
                    if (yr >= yi && yr <= yi + hi) {
                        return true;
                    }
                    if (yr + hr >= yi && yr + hr <= yi + hi) {
                        return true;
                    }
                }
                if (xr + wr < xi || xr + wr > xi + wi) {
                    continue;
                }
                if (yr >= yi && yr <= yi + hi) {
                    return true;
                }
                if (yr + hr >= yi && yr + hr <= yi + hi) {
                    return true;
                }
            }
        }
        return false;
    }

    @Override
    public void updateConfig() {
        this.layoutPage();
    }

    private class GDContainerPageMouseListener extends MouseInputAdapter {
        @Override
        public void mousePressed(final MouseEvent e) {
            this.selectItem(e);
        }

        @Override
        public void mouseMoved(final MouseEvent e) {
            GDItem item = null;
            if (GDContainerPane.this.uiTransfer != null) {
                item = GDContainerPane.this.uiTransfer.getSelectedItem();
            }
            if (item == null) {
                return;
            }
            final BufferedImage img = item.getImage();
            if (img == null) {
                return;
            }
            int x = e.getX();
            int y = e.getY();
            int xOff = GDContainerPane.this.getXOffset();
            int yOff = GDContainerPane.this.getYOffset();
            int w = GDContainerPane.this.getWidth();
            int h = GDContainerPane.this.getHeight();
            if (GDStashFrame.iniConfig.sectUI.graphicScale != 100) {
                xOff = xOff * GDStashFrame.iniConfig.sectUI.graphicScale / 100;
                yOff = yOff * GDStashFrame.iniConfig.sectUI.graphicScale / 100;
            }
            if (x < xOff || x > xOff + w || y < yOff || y > yOff + h) {
                return;
            }
            x -= xOff;
            y -= yOff;
            if (GDStashFrame.iniConfig.sectUI.graphicScale != 100) {
                x = x * 100 / GDStashFrame.iniConfig.sectUI.graphicScale;
                y = y * 100 / GDStashFrame.iniConfig.sectUI.graphicScale;
                w = w * 100 / GDStashFrame.iniConfig.sectUI.graphicScale;
                h = h * 100 / GDStashFrame.iniConfig.sectUI.graphicScale;
            }
            if (x < 10 || x > w - 10 || y < 10 || y > h - 10) {
                GDContainerPane.this.mouseRect = null;
            } else {
                x /= 32;
                y /= 32;
                x = x * 32 + GDImagePool.getSharedStashXOffset() + 1;
                y = y * 32 + GDImagePool.getSharedStashXOffset() + 1;
                GDContainerPane.this.mouseRect = new Rectangle(x, y, img.getWidth() - 2, img.getHeight() - 2);
            }
            GDContainerPane.this.layoutPage();
        }

        private void selectItem(final MouseEvent e) {
            if (GDContainerPane.this.container == null) {
                return;
            }
            final int button = e.getButton();
            if (button == 3 && GDContainerPane.this.uiInventory != null) {
                GDContainerPane.this.uiInventory.setSelectedItem(null);
            }
            if (button != 1) {
                return;
            }
            int x = e.getX();
            int y = e.getY();
            int xOff = GDContainerPane.this.getXOffset();
            int yOff = GDContainerPane.this.getYOffset();
            final int w = GDContainerPane.this.getWidth();
            final int h = GDContainerPane.this.getHeight();
            if (GDStashFrame.iniConfig.sectUI.graphicScale != 100) {
                xOff = xOff * GDStashFrame.iniConfig.sectUI.graphicScale / 100;
                yOff = yOff * GDStashFrame.iniConfig.sectUI.graphicScale / 100;
            }
            if (x < xOff || x > xOff + w || y < yOff || y > yOff + h) {
                GDContainerPane.this.layoutPage();
                return;
            }
            x -= xOff;
            y -= yOff;
            if (GDStashFrame.iniConfig.sectUI.graphicScale != 100) {
                x = x * 100 / GDStashFrame.iniConfig.sectUI.graphicScale;
                y = y * 100 / GDStashFrame.iniConfig.sectUI.graphicScale;
            }
            GDItem selItem = null;
            if (GDContainerPane.this.uiTransfer != null) {
                selItem = GDContainerPane.this.uiTransfer.getSelectedItem();
            }
            for (final GDItem item : GDContainerPane.this.container.getItemList()) {
                final BufferedImage img = item.getImage();
                if (img != null) {
                    final int x2 = item.getX() * 32 + GDImagePool.getSharedStashXOffset();
                    final int y2 = item.getY() * 32 + GDImagePool.getSharedStashYOffset();
                    final int x3 = x2 + img.getWidth();
                    final int y3 = y2 + img.getHeight();
                    if (x < x2 || x > x3 || y < y2 || y > y3) {
                        continue;
                    }
                    if (item != selItem) {
                        if (GDContainerPane.this.uiInventory != null) {
                            GDContainerPane.this.uiInventory.setSelectedItem(item);
                        }
                        selItem = item;
                        GDContainerPane.this.layoutPage();
                        return;
                    }
                    break;
                }
            }
            GDItem item2 = null;
            if (GDContainerPane.this.uiTransfer != null) {
                item2 = GDContainerPane.this.uiTransfer.getSelectedItem();
            }
            if (item2 != null && !GDContainerPane.this.isBlocked()) {
                GDContainerPane.this.mouseRect = null;
                if (GDContainerPane.this.uiTransfer.getItemLocation() == 1) {
                    GDContainerPane.this.uiTransfer.transferSelectedItem(1, e.getX(), e.getY());
                }
                if (GDContainerPane.this.uiTransfer.getItemLocation() == 2) {
                    GDContainerPane.this.uiTransfer.transferSelectedItem(4, e.getX(), e.getY());
                }
            }
        }
    }
}
